import type { FieldRule } from '@arco-design/web-vue'
import type { ManipulateType } from 'dayjs'
import dayjs from 'dayjs'
import { saveAs } from 'file-saver'
import JSZip from 'jszip'
/**
 * 处理空值
 * @param value 原数据
 * @returns
 */
export function emptyText(value: any, emptySign: string = '-') {
  if (value === '' || !value || (Array.isArray(value) && !value.length)) {
    return emptySign
  }
  return value
}
/**
 * 获取由LabelValue组成的数组里指定value的label
 * @param options
 * @param value
 * @returns
 */
export function getOptionsLabel(
  options: LabelValue[],
  value: string | number,
  target?: string,
) {
  return emptyText(
    options.find(item => item.value === value)?.[target || 'label'],
  )
}

export function fileSizeRule(
  list: LabelValue[],
  unit: number,
  tip: string,
): FieldRule {
  return {
    required: true,
    validator(value, callback) {
      const max = getOptionsLabel(list, unit, 'max')
      console.log(unit)
      if (!value) {
        return callback(tip || '请输入单文件最大大小')
      }
      if (value > Number(max)) {
        return callback(`最大值为${max}`)
      }
      return callback()
    },
  }
}

export function cacheSizeRule(unit: number): FieldRule {
  return {
    required: true,
    validator(value, callback) {
      const max = getOptionsLabel(diskOptions, unit, 'max')
      if (!value) {
        return callback('请输入单文件最大大小')
      }
      if (value > Number(max)) {
        return callback(`最大值为${max}`)
      }
      return callback()
    },
  }
}

export function indexSizeRule(unit: number): FieldRule {
  return {
    required: true,
    validator(value, callback) {
      const max = getOptionsLabel(indexSizeOptions, unit, 'max')
      if (!value) {
        return callback('请输入缓存索引容量')
      }
      if (value > Number(max)) {
        return callback(`最大值为${max}`)
      }
      return callback()
    },
  }
}

export function randomCname() {
  const char = 'abcdefghijklmnopqrstuvwxyz0123456789'
  let len = 6
  let result = ''
  while (len > 0) {
    const index = Math.floor(Math.random() * char.length)
    result += char[index]
    len--
  }
  return result
}

export const cnameRules: FieldRule = {
  required: true,
  validator(value, callback) {
    const reg = /^[0-9a-z]{6,20}$/

    if (!value) {
      callback('CNAME 不能为空')
    } else if (!reg.test(value)) {
      callback('请输入6 ~ 20 位小写字母和数字')
    } else {
      callback()
    }
  },
}

/**
 * 流量单位转化
 * @param {*} ？bytes 字节数
 * @param {*} ？unit 单位
 * @returns
 */
export function byteConvertSite(bytes: number, unit = 'B') {
  if ((bytes || bytes !== 0) && !Number.isNaN(bytes)) {
    let bits: number | string = bytes
    //   let bits: number | string = bytes * 8
    const symbols
      = unit === 'B'
        ? ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
        : [
            'bps',
            'Kbps',
            'Mbps',
            'Gbps',
            'Tbps',
            'Pbps',
            'Ebps',
            'Zbps',
            'Ybps',
          ]
    let exp = Math.floor(Math.log(bits) / Math.log(2))
    if (exp < 1) {
      exp = 0
    }
    const i = Math.floor(exp / 10)

    bits /= 2 ** (10 * i)
    if (bits.toString().length > bits.toFixed(2).toString().length) {
      bits = bits.toFixed(2)
    }
    if (Number.isNaN(bits) && !symbols[i])
      return '-'
    return `${bits} ${symbols[i]}`
  }
  return `0 ${unit === 'B' ? 'B' : 'bps'}`
}

// export function CdnBuildColumns(
//   columns: BuildTabColumnsData[],
// ): TableColumnData[] {
//   return columns.map((item) => {
//     if (!item?.disableTooltip) {
//       item.tooltip = true
//     }
//     if (!item?.disableEllipsis) {
//       item.ellipsis = true
//     }
//     if (item?.minWidth) {
//       item.cellStyle = {
//         minWidth: `${item.minWidth}px`,
//         ...(item.cellStyle || {}),
//       }
//     }
//     if (item?.maxWidth) {
//       item.cellStyle = {
//         maxWidth: `${item.maxWidth}px`,
//         ...(item.cellStyle || {}),
//       }
//     }
//     // item.width = lang === 'zh-CN' ? item.width : item.enWidth
//     if ((!item.slotName && !item?.render) || item?.format === 'empty') {
//       item.render = ({ record }) => {
//         const data = record[item.dataIndex!]
//         if (isBoolean(data))
//           return data
//         if (data === 0)
//           return data
//         if (data)
//           return data
//         return '-'
//       }
//     }
//     if (isString(item?.format)) {
//       if ((item?.format || '').startsWith('date') || item.format === 'time') {
//         item.render = ({ record }) => {
//           const data = record[item.dataIndex!]
//           if (!data || Number(data) === 0)
//             return '-'
//           let template = 'YYYY-MM-DD HH:mm:ss'
//           if (item.format === 'date') {
//             template = 'YYYY-MM-DD'
//           } else if (item.format === 'date-hour-minute') {
//             template = 'YYYY-MM-DD HH:mm'
//           } else if (item.format === 'time') {
//             template = 'HH:mm:ss'
//           }
//           return dayjs(data * 1000).format(template)
//         }
//       }

//       // 美元
//       if (item?.format === 'dollar') {
//         item.align = item?.align === undefined ? 'right' : item.align
//         item.render = ({ record }) => {
//           const data = record[item.dataIndex!]
//           if (!data || Number(data) === 0)
//             return '-'
//           const value = Decimal.div(data, 10000).toString()
//           return h('span', { class: 'text-primary' }, `${value}`)
//         }
//       }

//       if (item?.format === 'copy') {
//         item.render = ({ record }) => {
//           return h(
//             CopyField,
//             {
//               hoverTable: true,
//             },
//             {
//               default: () =>
//                 h(
//                   'span',
//                   {
//                     class: item.clickFn
//                       ? 'table-copy-text  cursor-pointer'
//                       : '',
//                     onClick: () => {
//                       if (item.clickFn) {
//                         item.clickFn(record)
//                       }
//                     },
//                   },
//                   record[item.dataIndex!] || '-',
//                 ),
//             },
//           )
//         }
//       }
//     }

//     if (isObject(item?.format) && item.format?.type === 'edit') {
//       item.render = ({ record }) => {
//         return h(EditField, {
//           content: record[item.dataIndex!] || '-',
//           ...omit(item.format as object, 'type'),
//         })
//       }
//     }

//     return item
//   })
// }

export function formatChartsUnix(time: number, timeUnit = 'day') {
  if (timeUnit === 'hour') {
    return formatUnix(time, 'MM-DD HH:mm:ss')
  }
  if (timeUnit === 'day') {
    return formatUnix(time, 'HH:mm')
  }
  if (timeUnit === 'week') {
    return formatUnix(time, 'MM-DD')
  }

  if (timeUnit === 'month') {
    return formatUnix(time, 'YYYY-MM-DD')
  }
  return '-'
}

/**
 * 获取填充后的折线图数据
 * @param {Record<string, any>[]} dataSource - 原始数据
 * @param {number} startTime - 开始时间戳
 * @param {number} endTime - 结束时间戳
 * @param {string} [field] - 数据字段名
 * @param {string} [timeFiled] - 时间字段名
 * @param {string} step - 步长
 * @param {string} delay - 延迟 传入延迟时间
 * @returns {LineChartDataReturn} - 填充后的折线图数据对象，包含seriesData（系列数据）、xAxisData（X轴数据）和unit（时间单位）
 */
export function getChartData(
  dataSource: any = [],
  startTime = 0,
  endTime = 0,
  field = '',
  timeFiled = 'time',
  step = 1,
  delay = 0,
) {
  const minute = endTime - startTime
  let unit = 'day'
  if (minute <= 86400) {
    unit = 'day'
  } else if (minute <= 86400 * 7) {
    unit = 'week'
  } else {
    unit = 'month'
  }

  const length: Record<string, () => number> = {
    day: () => minute / (step * 60),
    week: () => (minute + 1) / 3600,
    month: () => minute / 86400,
  }
  const addUnit: Record<string, string> = {
    day: 'minute',
    week: 'hours',
    month: 'days',
  }

  if (!startTime || !endTime || !field || !unit) {
    console.warn('startTime, endTime, field and unit are required parameters')
    return { seriesData: [], xAxisData: [] }
  }

  const keys = dataSource?.map((item: any) => Number(item[timeFiled]))

  const seriesData = dataSource?.map((item: any) => item[field])
  //   const xAxisData = Array.from({ length: length[unit]() + 1 }, (_, i) => {
  //     const time = dayjs(dayjs.unix(startTime))
  //       .add(unit === 'day' ? 5 * i : i + 1, addUnit[unit] as ManipulateType)
  //       .unix()
  //     if (!keys.includes(time)) {
  //       seriesData.splice(i, 0, getUnix() - 300 > time ? 0 : '-')
  //     }
  //     return time
  //   })

  const xAxisData = Array.from({ length: length[unit]() + 1 }, (_, i) => {
    const time = dayjs(dayjs.unix(startTime))
      .add(unit === 'day' ? step * i : i, addUnit[unit] as ManipulateType)
      .unix()
    if (!keys?.includes(time)) {
      // seriesData?.splice(i, 0, getUnix() - step * 60 > time + 60 ? 0 : '-')
      seriesData?.splice(i, 0, getUnix() - step * 60 > time + delay ? 0 : '-')
    }
    return time
  })
  return { seriesData, xAxisData, unit }
}

/**
 * 获取时间戳 如果不传date 获取当前时间
 * @param {*} ？date 时间
 * @returns
 */
export function getUnix(
  date?: string | number | Date | dayjs.Dayjs | null | undefined,
) {
  return dayjs(date).unix()
}

/**
 * 时间戳转日期时间
 * @param {number} date 时间戳
 * @param {string} template 转换格式
 * @returns
 */
export function formatUnix(
  date: number | string | undefined,
  template: string = 'YYYY-MM-DD HH:mm:ss',
): string {
  return date && date !== '0' ? dayjs.unix(Number(date)).format(template) : '-'
}

/**
 * 覆盖对象值
 * @param obj
 * @param value
 */
export function coverObjectValue<O extends object>(obj: O, value: object) {
  const keys = Object.keys(obj)
  for (const key of keys) {
    const v = Reflect.get(value, key)
    if (typeof v === 'boolean' || !!v) {
      obj[key] = v
    } else {
      obj[key] = ''
    }
  }
}

/**
 * 将字符串中的数字和字母分离
 * @param str 包含数字和字母的字符串
 * @returns 包含两个属性的对象，value为字符串中的数字部分，unit为字符串中的字母部分
 */
export function separateNumberAndLetter(str: string) {
  const regex = /(\d+)([a-z]+)/i
  const matches = str.match(regex)
  return { value: matches![1], unit: matches![2] }
}
function findOtherItem(
  array: any,
  excludedKey: string,
  target: string = 'key',
) {
  for (const item of array) {
    if (item[target] !== excludedKey) {
      return item // 返回第一个不匹配excludedKey的项
    }
  }
  return null // 如果没有找到，返回null
}

// 从一个数组中对象过滤出另一个数组对应的键的数据
type IFilter = 'excludes' | 'includes'
export function filterFromArray(
  arr: any[],
  filterArr: string[],
  flied: string = 'value',
  type: IFilter = 'includes',
) {
  return arr.filter((item) => {
    return filterArr.find((v) => {
      if (type === 'excludes')
        return v !== item[flied]
      return v === item[flied]
    })
  })
}
/** 预览自定义页面 */
export function previewWithNewPage(body: string) {
  const newWin = window.open('', '', '')
  if (!newWin)
    return
  newWin.opener = null // 防止代码对论谈页面修改
  newWin.document.write(body || '')
  newWin.document.close()
}

// 计算到期时间剩余天数
export function calculateRemainingDays(timestamp: number | 0) {
  const now = Math.floor(Date.now() / 1000)
  const remainingTime = timestamp - now
  const days = Math.floor(remainingTime / (60 * 60 * 24))
  return days
}

// 字符串转txt下载
export function useDownloadTxt(content: string, fileName: string = 'log') {
  const blob = new Blob([content], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const aLink = document.createElement('a')
  aLink.href = url
  aLink.download = `${fileName}.txt`
  aLink.click()
  URL.revokeObjectURL(url)
  aLink.remove()
}

// 下载证书
export async function createCertZip(
  certPem: string,
  privateKey: string,
  zipName = 'cert.zip',
  certPemName = 'certificate.pem',
  privateKeyName = 'private.key',
) {
  const zip = new JSZip()

  // 添加证书文件（certificate.pem）
  zip.file(certPemName, certPem)

  // 添加私钥文件（private.key）
  zip.file(privateKeyName, privateKey)

  // 生成 ZIP 文件并触发下载
  const zipContent = await zip.generateAsync({ type: 'blob' })
  saveAs(zipContent, zipName)
}
